import { LevelData, Word, Point } from "./LevelData";
import CharView from "../View/CharView";

export enum BlockState {
    Hidden, // 暗字
    Shown, // 明字
    CharFlipped, // 暗字被翻开
    IdiomFlipped, // 整个成语被翻开
}

// 代表一个地图上的方块的数据
export class Block {
    char: string = '□'; // 方块上的字

    //state : BlockState; // 方块的状态

    isGray: boolean = true; // 方块是否空白块
    isHidden: boolean = false; // 是否暗字
    isCharFlipped: boolean = false; // 暗字是否被翻开
    isIdiomFlipped: boolean = false; // 暗字所在的整个成语是否被翻开

    // top:number;
    // left:number;
    pos: Point = <Point>{};

    wordIndices: number[] = []; // 字符关联的成语序号

    mapCharView : CharView = null;
    waitCharView : CharView = null;
}

/**
 * 本地的成语定义
 */
export class MyWord {
    blocks: Block[] = []; // 字块集合
}

/**
 * 本地的关卡定义
 */
export class MyLevel {
    words: MyWord[] = [];
}

// 把关卡数据转换成2维地图数组上的格子数据
export class MapData {
    //#region Singleton Method 1:
    private static instance: MapData = null;

    public static GetInstance(): MapData {
        if (MapData.instance == null) {
            MapData.instance = new MapData();
        }
        return MapData.instance;
    }

    private constructor() {
    }
    //#endregion

    //#region Singleton Method 2:
    // public static instance : Map = null;

    // public constructor(){
    //     if (Map.instance == null){
    //         Map.instance = new Map();
    //     }
    //     return Map.instance;
    // }

    // // step 1:
    // let m1 : Map = new Map();
    // let m2 : Map = new Map();
    // // step 2:
    // console.log(m1 === m2);
    //#endregion

    public data: Block[][] = [];//new Block[9][9];

    public hiddenPoses: Point[] = []; // data[hiddenPoses[i].top][hiddenPoses[i].left]

    public myLevel: MyLevel = new MyLevel();

    public LoadLevel(ld: LevelData): boolean {
        // 加载关卡数据
        // 1.新建一个地图数组
        for (let row = 0; row < 9; row++) {
            let cols: Block[] = [];
            for (let col = 0; col < 9; col++) {
                cols.push(new Block());
            }
            this.data.push(cols);
        }

        // 遍历所有成语，生成地图数据
        for (let i = 0; i < ld.words.length; i++) {
            let word: Word = ld.words[i];

            // let dirTop:number = word.pos_mode=='h'?0:1;
            // let dirLeft:number = word.pos_mode=='h'?1:0;
            let dir: Point = {
                top: word.pos_mode == 'h' ? 0 : 1,
                left: word.pos_mode == 'h' ? 1 : 0,
            };
            let cur_pos: Point = new Point(word.start_pos.top, word.start_pos.left);

            // 遍历成语中的每一个字
            let myWord = new MyWord();
            for (let j = 0; j < word.idiom.length; j++) {
                // 生成每个字的属性
                let cur_block = this.data[cur_pos.top][cur_pos.left];

                cur_block.char = word.idiom[j];
                cur_block.pos.top = cur_pos.top;
                cur_block.pos.left = cur_pos.left;
                cur_block.wordIndices.push(i);
                cur_block.isGray = false;

                cur_block.isHidden = false;
                for (let k = 0; k < word.quest_indices.length; k++) {
                    if (j == word.quest_indices[k]) {
                        cur_block.isHidden = true;
                    }
                }
                cur_block.isCharFlipped = false;
                cur_block.isIdiomFlipped = false;

                // 去重被行列共享的成语中的汉字，把去重后的暗字加入暗字索引列表
                if (cur_block.isHidden) {
                    let exist = false;
                    for (let i = 0; i < this.hiddenPoses.length; i++) {
                        if (this.hiddenPoses[i].top == cur_pos.top
                            && this.hiddenPoses[i].left == cur_pos.left) {
                            exist = true;
                        }
                    }
                    if (!exist) {
                        this.hiddenPoses.push(new Point(cur_pos.top, cur_pos.left));
                    }
                }

                myWord.blocks.push(cur_block);

                cur_pos.top = cur_pos.top + dir.top;
                cur_pos.left = cur_pos.left + dir.left;
            }
            this.myLevel.words.push(myWord);
        }

        // 调试输出地图数据
        for (let row = 0; row < this.data.length; row++) {
            let s: string = '';
            for (let col = 0; col < this.data[0].length; col++) {
                s += this.data[row][col].isHidden ? '■' : this.data[row][col].char;
            }
            console.log(s);
        }

        return true;
    }
}